///*
// * Copyright © OpenAtom Foundation.
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *      http://www.apache.org/licenses/LICENSE-2.0
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
// * See the License for the specific language governing permissions and
// * limitations under the License.
// *
// */
//
//package io.iec.edp.caf.rpc.api.serialize;
//
//import com.fasterxml.jackson.databind.ObjectMapper;
//import io.iec.edp.caf.commons.core.SerializerFactory;
//import io.iec.edp.caf.commons.core.enums.SerializeType;
//import io.iec.edp.caf.commons.exception.CAFRuntimeException;
//
//import io.iec.edp.caf.commons.exception.entity.DefaultExceptionProperties;
//import io.iec.edp.caf.commons.exception.entity.ExceptionErrorCode;
//import io.iec.edp.caf.commons.exception.ExceptionLevel;
//import io.iec.edp.caf.commons.utils.InvokeService;
//import io.iec.edp.caf.rpc.api.annotation.GspParamSerializeType;
//import io.iec.edp.caf.rpc.api.annotation.RpcParam;
//
//import io.iec.edp.caf.rpc.api.common.GspSerializeType;
//import io.iec.edp.caf.rpc.api.entity.RpcParamDefinition;
//import io.iec.edp.caf.rpc.api.utils.RpcAppContextUtils;
//import lombok.extern.slf4j.Slf4j;
//import lombok.var;
//import org.springframework.core.DefaultParameterNameDiscoverer;
//
//import java.lang.reflect.GenericArrayType;
//import java.lang.reflect.Parameter;
//import java.lang.reflect.ParameterizedType;
//import java.lang.reflect.Type;
//import java.util.HashMap;
//import java.util.LinkedHashMap;
//import java.util.List;
//import java.util.Map;
//import java.util.concurrent.ConcurrentHashMap;
//
//@Slf4j
//public class ParameterSerializeUtil {
//
//    public LinkedHashMap<String, String> serializeParameter(
//            HashMap<String, Object> paramDict,
//            List<RpcParamDefinition> paramConfiguration) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
//
//        LinkedHashMap<String, String> stringDict = new LinkedHashMap<String, String>();
//        if (paramDict == null)
//            return stringDict;
//        for (var key : paramDict.keySet()) {
//            var serializeType = GspSerializeType.Json;
//            String customAssembly = "";
//            if (paramConfiguration != null && paramConfiguration.size() > 0) {
//                RpcParamDefinition paramInfo = new RpcParamDefinition();
//                if (paramConfiguration.stream().anyMatch(para -> para.getName().equals(key)))
//                    paramInfo = paramConfiguration.stream().filter(para -> para.getName().equals(key)).findFirst().get();
//                serializeType = paramInfo.getSerializeType();
//                customAssembly = paramInfo.getSerializer();
//            }
//
//            var value = paramDict.get(key);
//            String valueStr;
//            switch (serializeType) {
//                case Json:
//                    valueStr = SerializerFactory.getDeserializer(SerializeType.Json).serializeToString(value);
//                    break;
//                case Custom:
//                    valueStr = getCustomSerializeClass(customAssembly).serialize(value);
//                    break;
//                default:
//                    throw new CAFRuntimeException(DefaultExceptionProperties.SERVICE_UNIT,
//                            DefaultExceptionProperties.RESOURCE_FILE,
//                            ExceptionErrorCode.serializeMethodNotSupport,
//                            new String[]{serializeType.toString()}, null, ExceptionLevel.Error, false);
//            }
//            stringDict.put(key, valueStr);
//        }
//        return stringDict;
//    }
//
//    private ConcurrentHashMap<String, RpcCustomSerializer> customSerializersMap;
//
//    private RpcCustomSerializer getCustomSerializeClass(String implementClass) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
//        if (this.customSerializersMap == null) {
//            this.customSerializersMap = new ConcurrentHashMap<>();
//        }
//
//        RpcCustomSerializer rpcCustomSerializer = this.customSerializersMap.get(implementClass);
//
//        if (rpcCustomSerializer == null) {
//            rpcCustomSerializer = (RpcCustomSerializer) InvokeService.getClassByName(implementClass).newInstance();
//            this.customSerializersMap.put(implementClass, rpcCustomSerializer);
//        }
//
//        return rpcCustomSerializer;
//    }
//
//    private static ObjectMapper objectMapper = new ObjectMapper();
//
//    public Object[] deSerializeParameter(
//            Class iType, Class type, Map<String, String> paramDict, String methodName) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
//
//        var methodInfo = RpcAppContextUtils.getMethodByName(type, methodName);//type.getDeclaredMethod(methodName);
//        var iMethodInfo = RpcAppContextUtils.getMethodByName(iType, methodName);
//        var parameterInfos = methodInfo.getParameters();
//        var iParameterInfos = iMethodInfo.getParameters();
//
//        Object[] paramArray = new Object[paramDict.size()];
//
//        //方法参数名集合
//        DefaultParameterNameDiscoverer discover = new DefaultParameterNameDiscoverer();
//        var paramsTruthNames = discover.getParameterNames(methodInfo);
//        GspParamSerializeType[] annotations = methodInfo.getDeclaredAnnotationsByType(GspParamSerializeType.class);
//
//        for (int i = 0; i < parameterInfos.length; i++) {
//            //参数绑定与反序列化
//            //判断是否有RpcParam注解 有的话从注解拿 没有的话从TruthName拿
//            Parameter parameter = parameterInfos[i];
//            Parameter iParameter = iParameterInfos[i];
//
//            RpcParam rpcParam = iParameter.getDeclaredAnnotation(RpcParam.class);
//            String paramName = rpcParam == null ? paramsTruthNames[i] : rpcParam.paramName();
//
//            //参数值
//            var paramValue = paramDict.get(paramName);
//
//            var paramType = parameter.getParameterizedType();
//            var javaType = objectMapper.constructType(paramType);
//
//            //序列化方式
//            GspSerializeType serializeType;
//            String customClass;
//            if (rpcParam != null) {
//                //先从RpcParam取
//                serializeType = rpcParam.paramSerializeType();
//                customClass = rpcParam.customSerializeTypeRef();
//            } else {
//                //再从GspParamSerializeType取
//                GspParamSerializeType gspParamSerializeType = getParamAnnotation(paramName, annotations);
//                if (gspParamSerializeType == null) {
//                    //都没有则为默认
//                    serializeType = GspSerializeType.Json;
//                    customClass = "";
//                } else {
//                    serializeType = gspParamSerializeType.paramSerializeType();
//                    customClass = gspParamSerializeType.customSerializeTypeRef();
//                }
//
//                log.warn("未找到RpcParam注解 请尽快添加。Rpc接口类: " + iType.getName());
//            }
//
//            Object value;
//            switch (serializeType) {
//                case Json:
//                    value = SerializerFactory.getSerializer(SerializeType.Json).deserialize(paramValue, javaType);
//                    //value = objectMapper.readValue(paramValue, javaType);
//                    break;
//                case Custom:
////                    var paramSerializer =
//                    //获取参数的真实类型 并反序列化
//                    Type tempType = paramType;
//                    while (!(tempType instanceof Class)) {
//                        if (tempType instanceof ParameterizedType) {
//                            tempType = ((ParameterizedType) tempType).getRawType();
//                        } else if (tempType instanceof GenericArrayType) {
//                            tempType = ((GenericArrayType) tempType).getGenericComponentType();
//                        } else {
//                            throw new RuntimeException("unsupport Type: " + tempType.getTypeName());
//                        }
//                    }
//
//                    Class clazz = (Class) tempType;
//                    value = getCustomSerializeClass(customClass).deserialize(paramValue, clazz);
//                    //value = objectMapper.readValue(paramValue, javaType);
//                    break;
//                default:
//                    throw new CAFRuntimeException(DefaultExceptionProperties.SERVICE_UNIT,
//                            DefaultExceptionProperties.RESOURCE_FILE,
//                            ExceptionErrorCode.serializeMethodNotSupport,
//                            new String[]{serializeType.toString()}, null, ExceptionLevel.Error, false);
//            }
//            paramArray[i] = value;
//        }
//        return paramArray;
//    }
//
//    private GspParamSerializeType getParamAnnotation(String name, GspParamSerializeType[] annotations) {
//        for (GspParamSerializeType annotation : annotations) {
//            if (name.equals(annotation.paramName())) {
//                return annotation;
//            }
//        }
//
//        return null;
//    }
//
//    private static boolean hasElement(String[] args, String ele) {
//        boolean check = false;
//        for (var a : args) {
//            if (a.equalsIgnoreCase(ele)) {
//                check = true;
//                break;
//            }
//        }
//
//        return check;
//    }
//}
